﻿using System;
using InterfaceLiftLib.Attributes;
using InterfaceLiftLib.Service;
using InterfaceLiftLib.Service.Implementations;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace InterfaceLiftTests
{
    [TestClass]
    public class CamelCaseUrlBuilderShould
    {
        private const string FakeBaseUrl = "http://foo.it";
        private IUrlBuilder m_urlBuilder;

        [TestInitialize]
        public void Init()
        {
            m_urlBuilder = new CamelCaseUrlBuilder();
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ThrowIfMethodInfoIsNull()
        {
            m_urlBuilder.BuildUrl(FakeBaseUrl, null, 1, 2, 3);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void ThrowIfNumberOfArgsIsHigherThanMethodInfosNumberOfParamters()
        {
            var methodInfo = this.GetType().GetMethod("FakeMethodForTest");
            m_urlBuilder.BuildUrl(FakeBaseUrl, methodInfo, 10, "myName", "555 123", "one more param");
        }

        [TestMethod]
        public void CreateValidUrl()
        {
            var fakeMethodForTest = this.GetType().GetMethod("FakeMethodForTest");
            var url = m_urlBuilder.BuildUrl(FakeBaseUrl, fakeMethodForTest, 10, "myname", "555 123");
            Assert.AreEqual(FakeBaseUrl + "/FakeMethodForTest/10/myname/555%20123/", url, "#1");

            var fakeMethodWithAttributes = this.GetType().GetMethod("FakeMethodWithAttributes");
            url = m_urlBuilder.BuildUrl(FakeBaseUrl, fakeMethodWithAttributes, 10, 25, "foo", "last words");
            Assert.AreEqual(FakeBaseUrl + "/FMWA/10/?limit=25&starts_with=foo&ends_with=last%20words", url, "#2");
        }

        [TestMethod]
        public void NotReturnNullOrDefaultQueryStringParams()
        {
            var methodInfo = this.GetType().GetMethod("FakeMethodWithAttributes");

            var url = m_urlBuilder.BuildUrl(FakeBaseUrl, methodInfo, 0, 0, null, null);
            Assert.AreEqual(FakeBaseUrl + "/FMWA/0/", url);
            
            url = m_urlBuilder.BuildUrl(FakeBaseUrl, methodInfo, 12, 25, "start words", null);
            Assert.AreEqual(FakeBaseUrl + "/FMWA/12/?limit=25&starts_with=start%20words", url);
        }

        //.../FakeMethodForTest/{id}/{name}/{phoneNumber}/
        public void FakeMethodForTest(int id, string name, string phoneNumber) { }

        //.../FMFT/{id}/?limit={limit}&keyword&starts_with={startsWith}
        [WebServiceMethodName("FMWA")]
        public void FakeMethodWithAttributes(int id, [QueryStringParameter]int limit, [QueryStringParameter]string startsWith, [QueryStringParameter]string endsWith) { }
    }
}
